/**
 * 数据处理类，可以根据项目自行配置
 */
import type { AxiosRequestConfig, AxiosResponse } from 'axios'
import type { RequestOptions, Result } from './types'
import { RequestEnum, ResultEnum } from '@/enums/httpEnum'
import { message as Message, Modal } from 'ant-design-vue'
import router from '@/router'
import { storage } from '@/utils/Storage'
import { isString } from '@/utils/is'
import { setObjToUrlParams } from '@/utils/urlUtils'
import { useAuthStore } from '@/store/modules/auth'
import axios from 'axios'
import { checkStatus } from '@/utils/http/axios/checkStatus'
import qs from 'qs'

export abstract class AxiosTransform {
  /**
   * @description: 请求之前处理配置
   * @description: Process configuration before request
   */
  beforeRequestHook?: (config: AxiosRequestConfig, options: RequestOptions) => AxiosRequestConfig

  /**
   * @description: 请求成功处理
   */
  transformRequestData?: (res: AxiosResponse<Result>, options: RequestOptions) => any

  /**
   * @description: 请求失败处理
   */
  requestCatch?: (e: Error) => Promise<any>

  /**
   * @description: 请求之前的拦截器
   */
  requestInterceptors?: (config: AxiosRequestConfig) => AxiosRequestConfig

  /**
   * @description: 请求之后的拦截器
   */
  responseInterceptors?: (res: AxiosResponse<Result>) => AxiosResponse

  /**
   * @description: 请求之前的拦截器错误处理
   */
  requestInterceptorsCatch?: (error: Error) => void

  /**
   * @description: 请求之后的拦截器错误处理
   */
  responseInterceptorsCatch?: (error: Error) => void
}

/**
 * @description: 数据处理，方便区分多种处理方式
 */
export const cfTransform: AxiosTransform = {
  /**
   * @description: 处理请求数据
   */
  transformRequestData: (res: AxiosResponse<Result>, options: RequestOptions) => {
    // const {
    //   isTransformRequestResult,
    //   isShowMessage = true,
    //   isShowErrorMessage,
    //   isShowSuccessMessage,
    //   successMessageText,
    //   errorMessageText
    // } = options
    //
    // const reject = Promise.reject
    //
    // const { data } = res
    // //  这里 code，result，message为 后台统一的字段，需要在 types.ts内修改为项目自己的接口返回格式
    // const { code, result, message } = data
    // // 请求成功
    // const hasSuccess = data && Reflect.has(data, 'code') && code === ResultEnum.SUCCESS
    // // 是否显示提示信息
    // if (isShowMessage) {
    //   if (hasSuccess && (successMessageText || isShowSuccessMessage)) {
    //     // 是否显示自定义信息提示
    //     Message.success(successMessageText || message || '操作成功！')
    //   } else if (!hasSuccess && (errorMessageText || isShowErrorMessage)) {
    //     // 是否显示自定义信息提示
    //     Message.error(message || errorMessageText || '操作失败！')
    //   } else if (!hasSuccess && options.errorMessageMode === 'modal') {
    //     // errorMessageMode=‘custom-modal’的时候会显示modal错误弹窗，而不是消息提示，用于一些比较重要的错误
    //     Modal.confirm({ title: '错误提示', content: message })
    //   }
    // }
    // // 不进行任何处理，直接返回
    // // 用于页面代码可能需要直接获取code，data，message这些信息时开启
    // if (!isTransformRequestResult) {
    //   return res.data
    // }
    //
    // if (!data) {
    //   // return '[HTTP] Request has no return value';
    //   return reject(data)
    // }
    //
    // // 接口请求成功，直接返回结果
    // if (code === ResultEnum.SUCCESS) {
    //   return result
    // }
    // // 接口请求错误，统一提示错误信息
    // if (code === ResultEnum.ERROR) {
    //   if (message) {
    //     Message.error(data.message)
    //     Promise.reject(new Error(message))
    //   } else {
    //     const msg = '操作失败,系统异常!'
    //     Message.error(msg)
    //     Promise.reject(new Error(msg))
    //   }
    //   return reject()
    // }
    //
    // // 登录超时
    // if (code === ResultEnum.TIMEOUT) {
    //   if (router.currentRoute.value.name == 'login') return
    //   // 到登录页
    //   const timeoutMsg = '登录超时,请重新登录!'
    //   Modal.destroyAll()
    //   Modal.warning({
    //     title: '提示',
    //     content: '登录身份已失效,请重新登录!',
    //     onOk: () => {
    //       router.replace({
    //         name: 'login',
    //         query: {
    //           redirect: router.currentRoute.value.fullPath
    //         }
    //       })
    //       storage.clear()
    //     }
    //   })
    //   return reject(new Error(timeoutMsg))
    // }
    //
    // // 这里逻辑可以根据项目进行修改
    // if (!hasSuccess) {
    //   return reject(new Error(message))
    // }

    return res
  },

  // 请求之前处理config
  beforeRequestHook: (config, options) => {
    const isDev = import.meta.env.DEV
    const { apiUrl, joinPrefix, joinParamsToUrl, formatDate, isParseToJson } = options

    config.url = isDev ? `/api${config.url}` : `${apiUrl || ''}${config.url}`

    if (config.method === RequestEnum.GET) {
      const now = new Date().getTime()
      if (!isString(config.params)) {
        config.data = {
          // 给 get 请求加上时间戳参数，避免从缓存中拿数据。
          params: Object.assign(config.params || {}, {
            _t: now
          })
        }
      } else {
        // 兼容restful风格
        config.url = config.url + config.params + `?_t=${now}`
        config.params = {}
      }
    } else {
      if (!isString(config.params)) {
        config.data = config.params
        config.params = {}
        if (joinParamsToUrl) {
          config.url = setObjToUrlParams(config.url as string, config.data)
        }
      } else {
        // 兼容restful风格
        config.url = config.url + config.params
        config.params = {}
      }
      // 'a[]=b&a[]=c'
      if (!isParseToJson) {
        config.params = qs.stringify(config.params, { arrayFormat: 'brackets' })
        config.data = qs.stringify(config.data, { arrayFormat: 'brackets' })
      }
    }
    return config
  },

  /**
   * @description: 请求拦截器处理
   */
  requestInterceptors: (config) => {
    // 请求之前处理config
    const authStore = useAuthStore()
    const token = authStore.state.token
    if (token) {
      // jwt token
      // config.headers.token = token
      config.headers.Authorization = token
    }
    return config
  },

  /**
   * @description: 响应错误处理
   */
  responseInterceptorsCatch: (error: any) => {
    const { response, code, message } = error || {}
    const msg: string =
      response && response.data && response.data.error ? response.data.error.message : ''
    const err: string = error.toString()
    try {
      if (code === 'ECONNABORTED' && message.indexOf('timeout') !== -1) {
        Message.error('接口请求超时,请刷新页面重试!')
        return
      }
      if (err && err.includes('Network Error')) {
        Modal.confirm({
          title: '网络异常',
          content: '请检查您的网络连接是否正常!'
        })
        return
      }
    } catch (error) {
      throw new Error(error)
    }
    // 请求是否被取消
    const isCancel = axios.isCancel(error)
    if (!isCancel) {
      checkStatus(error.response && error.response.status, msg)
    } else {
      console.warn(error, '请求被取消！')
    }
    return error
  },

  responseInterceptors: (res: AxiosResponse<Result>): AxiosResponse<Result> => {
    const result = res.data

    if (!result.success) {
    }

    return res
  }
}
